package com.cross.excel;

import java.io.File;
import java.util.List;

import jxl.Cell;
import jxl.Range;
import jxl.Workbook;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

import com.cross.core.AbstractReader;
import com.cross.core.Column;
import com.cross.core.Header;
import com.cross.core.Item;
import com.cross.core.Row;
import com.cross.exception.FileValidatorException;
import com.cross.util.ItemType;
import com.cross.util.StringUtils;

/**
 * excel读取器实现类
 *
 * 2009-2-5
 * @author craziness_stone
 */
@SuppressWarnings("unchecked")
public class SimpleExcelReader extends AbstractReader {

	// excel对象
	private WritableWorkbook book = null;
	// 当前Sheet
	private WritableSheet sheet = null;
	// 当前Sheet号
	private int sheetIndex = 0;
	// book中sheet数量
	private int bookSize = 0;
	// 当前工作表的行数
	private int rowNum = 0;
	//当前工作表中的所有合并的单元格
	private Range[] mergedCells;
	
	private File temp;
	
	public SimpleExcelReader(String file) throws Exception{
		if (StringUtils.isEmpty(file)) {
			throw new FileValidatorException("文件不存在.");
		}
		File temp = new File(file);
		if(temp==null || !temp.exists() || !temp.isFile()){
			throw new FileValidatorException("文件不存在.");
		}
		init(temp);
	}
	public SimpleExcelReader(File file) throws Exception{
		if (null == file) {
			throw new FileValidatorException("文件不存在.");
		}
		init(file);
	}
	/**
	 * 初始化
	 * 
	 * 2009-2-5
	 * @author craziness_stone
	 * @param file
	 * @throws Exception
	 */
	private void init(File file) throws Exception {
		book = getWorkbook(file);
		bookSize = book.getNumberOfSheets();
		if (book == null || bookSize < 1) {
			throw new FileValidatorException("文件中没有任何工作薄");
		}
		if(!_nextSheet()){
			throw new FileValidatorException("文件中没有任何工作薄");
		}
	}
	/**
	 * 获得工作表
	 * 
	 * 2008-12-19
	 * 
	 * @author craziness_stone
	 * @param file
	 * @return
	 */
	private WritableWorkbook getWorkbook(File file) throws Exception {
		try {
			// 打开Excel模板
			Workbook template = Workbook.getWorkbook(file);
			// 装载模板
			synchronized (this) {
				temp = new File("cross_" + System.currentTimeMillis()
						+ ".xls");
			}
			temp.createNewFile();
			return Workbook.createWorkbook(temp, template);
			
		} catch (Exception e) {
			throw new FileValidatorException("无法解析上传文件.");
		}
	}
	
	protected boolean nextRow(){
		return _nextRow();
	}

	/**
	 * 下一行
	 * 
	 * 2009-1-19
	 * 
	 * @author craziness_stone
	 * @return
	 */
	private boolean _nextRow() {
		//如果一个sheet读完了,
		if (rowIndex >= rowNum) {
			if(!_nextSheet()){
				return false;
			}
		}
		currentRow = toRow(sheet.getRow((int)rowIndex++));
		currentRow.setNumber(totalIndex++);
		if (currentRow.empty()) {
			return _nextRow();
		}
		return true;
	}
	

//	private Cell[] getRow(){
//		if(mergedCells==null || mergedCells.length<1){
//			return sheet.getRow((int)rowIndex);
//		}
//		Cell cell = null;
//		Cell temp = null;
//		for(Range r : mergedCells){
//			temp = r.getTopLeft();
//			if(temp.getRow()==(int)rowIndex){
//				if(cell==null){
//					cell = temp;
//				}
//				if(cell.getColumn()>temp.getColumn()){
//					cell = temp;
//				}
//			}
//		}
//		
//		return null;
//	}

	private Row toRow(Cell[] cells){
		List<Column> columns = header.getColumns();
		Row r = new Row();
		Item item = null;
		Column column = null;
		Cell cell = null;
		for(int i=0; i < columns.size() || i < cells.length; i++){
			column = header.getColumn(i);
			cell = cells[i];
			item = new Item<String>(cell.getContents(),column.getType(), column.getPrecision());
			item.setColumn(i);
			r.append(item);
		}
		return r;
	}
	/**
	 * 下一个工作表
	 * 
	 * 2009-1-17
	 * 
	 * @author craziness_stone
	 * @return
	 */
	private boolean _nextSheet() {
		if (sheetIndex >= bookSize) {
			return false;
		}
		sheet = book.getSheet(sheetIndex++);
//		this.mergedCells = sheet.getMergedCells();
		rowNum = sheet.getRows();
		rowIndex = 2;//从第二行开始是数据行.
		if(rowNum < 2){
			return _nextSheet();
		}
		String objectName = sheet.getName();
		Cell[] titleCells = sheet.getRow(0);
		Cell[] structCells = sheet.getRow(1);
		
		int endIndex = objectName.lastIndexOf('-');
		if(endIndex != -1){
			objectName = objectName.substring(0, endIndex);
		}
		
		try {
			header = toHeader(objectName, titleCells, structCells);
		} catch (RuntimeException e) {
			return _nextSheet();
		}
		return true;
	}
	
	private Header toHeader(String objectName, Cell[] titleCells, Cell[] structCells){
		Header header = new Header();
		header.setObjectName(objectName);
		if(titleCells == null || structCells == null || titleCells.length != structCells.length){
			throw new RuntimeException("没有头数据");
		}
		String temp = null;
		String type = null;
		int precision = 0;
		Boolean variable = true;
		String[] pArray = null;
		for(int i=0; i<titleCells.length; i++){
			temp = structCells[i].getContents();
			if(temp == null){
				throw new RuntimeException(titleCells[i].getContents()+"没有结构信息");
			}
			pArray = temp.split(",");
			if(pArray == null || pArray.length != 3){
				throw new RuntimeException(titleCells[i].getContents()+"结构信息不正确");
			}
			type = pArray[0];
			precision = Integer.parseInt(pArray[1]);
			variable = new Boolean(Boolean.parseBoolean(pArray[2]));
			header.add(new Column(i, titleCells[i].getContents(), type, precision, variable));
		}
 		return header;
	}


	/**
	 * 关闭工作表
	 * 
	 * 2009-1-20
	 * 
	 * @author craziness_stone 
	 */
	@Override
	public void close() {
		try {
			book.write();
			book.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			temp.delete();
		}
	}
}